#pragma once
#include "message.hpp"
#include "net.hpp"
namespace bitpr
{

    class Callback
    {
    public:
        using ptr = std::shared_ptr<Callback>;

        virtual void onMessage(const BaseConnection::ptr &conn, BaseMessage::ptr &msg) = 0;

    private:
    };
    template <typename T>
    class CallbackT : public Callback
    {
    public:
        using ptr = std::shared_ptr<CallbackT<T>>;
        using MessageCallback = std::function<void(const BaseConnection::ptr &conn, std::shared_ptr<T> &msg)>;
        CallbackT(const MessageCallback& handler) : _handler(handler){}
        void onMessage(const BaseConnection::ptr &conn, BaseMessage::ptr &msg) override
        {
            auto type_msg = std::dynamic_pointer_cast<T>(msg);//把分类对象转化为子类对象
            _handler(conn, type_msg);
        }

    private:
        MessageCallback _handler;
    };
    class Dispacher
    { 
    public:
        using ptr = std::shared_ptr<Dispacher>;
        template <typename T>
        void registerHandler(MType mtype, const typename CallbackT<T>::MessageCallback &handler)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto cb=std::make_shared<CallbackT<T>>(handler);
            _handlers.insert(std::make_pair(mtype, cb));
        }
        void onMessage(const BaseConnection::ptr &conn, BaseMessage::ptr msg)
        {
            // 找到相同的类型的业务处理函数,进行调用
            std::unique_lock<std::mutex> lock(_mutex);
            auto it = _handlers.find(msg->mtype());
            if (it != _handlers.end())
            {
                return it->second->onMessage(conn, msg);
            }
            // 没有找到这个指定类型的回调
            ELOG("收到未知类型消息");
            conn->shutdown();
        }

    private:
        std::unordered_map<MType, Callback::ptr> _handlers;
        std::mutex _mutex;
    };

}